import { Injectable } from '@angular/core';
import * as d3 from "d3";
import { TableTrComponent } from 'ng-devui';
import { comment, diagram, link, node } from 'src/classes/uielements';
import { CommonService } from './common.service';
@Injectable({
  providedIn: 'root'
})
export class VisualService {

  constructor() { }

  // 因为绘图需要集中注意力，每个应用，每次绘图操作只能操作同一组数据，所以绘图的数据是全局静态的
  //#region d3 draw 
  static linkpointclass = 'linkpoint'
  static scalepointclass = 'scalepoint'
  static activepoint = 'activepoint'
  static activepointR = 3
  static targetline = undefined
  static currentlinkpoint = undefined

  static selectedrectid = undefined
  public static moveline(canvasId, xProperty, yProperty, line, evt) {
    let svg = VisualService.getCanvas(canvasId)
    svg.select('#' + line.attr("id")).
      attr(xProperty, evt.evt.offsetX).
      attr(yProperty, evt.evt.offsetY)

  }

  public static currentdragline = undefined
  // static rectactivepointdrag = (target) => {
  //   d3.drag()
  //     .on("start", function (a) { //dragstart的监听器
  //       console.log("拖曳开始");
  //     })
  //     .on("end", function (d) {  //dragend的监听器
  //       console.log("搁曳结束");
  //     })
  //     .on("drag", function (event, node) {
  //       //console.log(d);
  //       console.log(d3.pointer(event, node));
  //       let mx = event.x
  //       let my = event.y
  //       let dx = event.dx
  //       let dy = event.dy

  //       var t = d3.select(this);
  //       if (t.attr("tag") === "l") {
  //         let right = Number(target.attr("x")) + Number(target.attr("width"))

  //         if (mx < right) {
  //           t.attr("cx", mx)
  //           target.attr("x", mx)
  //           target.attr("width", right - mx)
  //         }
  //       }

  //       if (t.attr("tag") === "t") {
  //         let bottom = Number(target.attr("y")) + Number(target.attr("height"))

  //         if (my < bottom) {
  //           t.attr("cy", my)
  //           target.attr("y", my)
  //           target.attr("height", bottom - my)
  //         }
  //       }

  //       if (t.attr("tag") === "r") {
  //         if (mx > Number(target.attr("x"))) {
  //           t.attr("cx", mx)
  //           target.attr("width", mx - Number(target.attr("x")))
  //         }
  //       }

  //       if (t.attr("tag") === "b") {
  //         if (my > Number(target.attr("y"))) {
  //           t.attr("cy", my)
  //           target.attr("height", my - Number(target.attr("y")))
  //         }
  //       }

  //     });

  // }
  public static refreshActivePoint(canvasId, target, r) {//此时target务必处于active的状态，这样重新修正所有的激活点位置

    let id = (target.attr("id"))
    let l = Number(target.attr("x"))
    let t = Number(target.attr("y"))
    let w = Number(target.attr("width"))
    let h = Number(target.attr("height"))
    let svg = VisualService.getCanvas(canvasId)

    let scalepoint = svg.select('#' + VisualService.scalepointclass + '_lt_' + id)

    if (scalepoint !== undefined) {

      scalepoint.attr('x', l - VisualService.activepointR)
      scalepoint.attr('y', t - VisualService.activepointR)
    }

    scalepoint = svg.select('#' + VisualService.scalepointclass + '_rt_' + id)
    if (scalepoint !== undefined) {
      scalepoint.attr('x', l + w - VisualService.activepointR)
      scalepoint.attr('y', t - VisualService.activepointR)
    }
    scalepoint = svg.select('#' + VisualService.scalepointclass + '_lb_' + id)
    if (scalepoint !== undefined) {
      scalepoint.attr('x', l - VisualService.activepointR)
      scalepoint.attr('y', t + h - VisualService.activepointR)
    }
    scalepoint = svg.select('#' + VisualService.scalepointclass + '_rb_' + id)
    if (scalepoint !== undefined) {
      scalepoint.attr('x', l + w - VisualService.activepointR)
      scalepoint.attr('y', t + h - VisualService.activepointR)
    }
    scalepoint = svg.select('#' + VisualService.linkpointclass + '_l_' + id)
    if (scalepoint !== undefined) {
      scalepoint.attr('cx', l - VisualService.activepointR / 2)
      scalepoint.attr('cy', t + (h / 2) - VisualService.activepointR / 2)
    }
    scalepoint = svg.select('#' + VisualService.linkpointclass + '_t_' + id)
    if (scalepoint !== undefined) {
      scalepoint.attr('cx', l + (w / 2) - VisualService.activepointR / 2)
      scalepoint.attr('cy', t - VisualService.activepointR / 2)
    }
    scalepoint = svg.select('#' + VisualService.linkpointclass + '_r_' + id)
    if (scalepoint !== undefined) {
      scalepoint.attr('cx', l + w - VisualService.activepointR / 2)
      scalepoint.attr('cy', t + (h / 2) - VisualService.activepointR / 2)
    }
    scalepoint = svg.select('#' + VisualService.linkpointclass + '_b_' + id)
    if (scalepoint !== undefined) {
      scalepoint.attr('cx', l + (w / 2) - VisualService.activepointR / 2)
      scalepoint.attr('cy', t + h - VisualService.activepointR / 2)
    }
  }
  public static addLeftTopScalePoint(canvasId, target, pointR) {
    this.selectedrectid = target.attr('id')
    let move = (x, y) => {
      let l = Number(target.attr("x"))
      let t = Number(target.attr("y"))
      let w = Number(target.attr("width"))
      let h = Number(target.attr("height"))
      let nw = w
      let nh = h

      if (x > l + w || y > t + h)
        return
      nw = w - (x - l)
      nh = h - (y - t)


      if (nw > 0) {
        target.attr("x", x)
        target.attr("width", nw)
      }
      if (nh > 0) {
        target.attr("y", y)
        target.attr("height", nh)
      }
      VisualService.refreshActivePoint(canvasId, target, VisualService.activepointR)
    }

    let pointx = Number(target.attr("x"))
    let pointy = Number(target.attr("y"))
    let baseid = target.attr("id")

    return VisualService.addScalePoint(canvasId, target, pointx, pointy, pointR, VisualService.scalepointclass + '_lt_' + baseid, move, "nw-resize", 'lt')
  }
  public static addRightTopScalePoint(canvasId, target, pointR) {
    this.selectedrectid = target.attr('id')
    let move = (x, y) => {
      let l = Number(target.attr("x"))
      let t = Number(target.attr("y"))
      let w = Number(target.attr("width"))
      let h = Number(target.attr("height"))
      let nw = w
      let nh = h

      if (x < l || y > t + h)
        return
      nw = (x - l)
      nh = h - (y - t)


      if (nw > 0) {
        //target.attr("x", x)
        target.attr("width", nw)
      }
      if (nh > 0) {
        target.attr("y", y)
        target.attr("height", nh)
      }
      VisualService.refreshActivePoint(canvasId, target, VisualService.activepointR)
    }

    let pointx = Number(target.attr("x")) + Number(target.attr("width"))
    let pointy = Number(target.attr("y"))
    let baseid = target.attr("id")

    return VisualService.addScalePoint(canvasId, target, pointx, pointy, pointR, VisualService.scalepointclass + '_rt_' + baseid, move, "ne-resize", 'rt')
  }
  public static addLeftBottomScalePoint(canvasId, target, pointR) {
    this.selectedrectid = target.attr('id')
    let move = (x, y) => {
      let l = Number(target.attr("x"))
      let t = Number(target.attr("y"))
      let w = Number(target.attr("width"))
      let h = Number(target.attr("height"))
      let nw = w
      let nh = h

      if (x > l + w || y < t)
        return
      nw = w - (x - l)
      nh = (y - t)


      if (nw > 0) {
        target.attr("x", x)
        target.attr("width", nw)
      }
      if (nh > 0) {
        //target.attr("y", y)
        target.attr("height", nh)
      }
      VisualService.refreshActivePoint(canvasId, target, VisualService.activepointR)
    }

    let pointx = Number(target.attr("x"))
    let pointy = Number(target.attr("y")) + Number(target.attr("height"))
    let baseid = target.attr("id")

    return VisualService.addScalePoint(canvasId, target, pointx, pointy, pointR, VisualService.scalepointclass + '_lb_' + baseid, move, "sw-resize", 'lb')
  }
  public static addRightBottomScalePoint(canvasId, target, pointR) {
    this.selectedrectid = target.attr('id')
    let move = (x, y) => {
      let l = Number(target.attr("x"))
      let t = Number(target.attr("y"))
      let w = Number(target.attr("width"))
      let h = Number(target.attr("height"))
      let nw = w
      let nh = h

      if (x < l || y < t)
        return
      nw = (x - l)
      nh = (y - t)


      if (nw > 0) {
        //target.attr("x", x)
        target.attr("width", nw)

      }
      if (nh > 0) {
        //target.attr("y", y)
        target.attr("height", nh)
      }
      VisualService.refreshActivePoint(canvasId, target, VisualService.activepointR)
    }

    let pointx = Number(target.attr("x")) + Number(target.attr("width"))
    let pointy = Number(target.attr("y")) + Number(target.attr("height"))
    let baseid = target.attr("id")

    return VisualService.addScalePoint(canvasId, target, pointx, pointy, pointR, VisualService.scalepointclass + '_rb_' + baseid, move, "se-resize", 'rb')
  }
  public static addScalePoint(canvasId, target, pointx: number, pointy, pointR, id, dragmove: Function, cursor: string, tag: string) {
    this.selectedrectid = target.attr('id')

    let drag = d3.drag()
      .on("start", function (event) { //dragstart的监听器
        console.log("拖曳开始");

        // VisualService.currentdragline = VisualService.drawLine(canvasId, event.sourceEvent.offsetX, event.sourceEvent.offsetY, event.sourceEvent.offsetX, event.sourceEvent.offsetY, 2, 'black')
        // target.attr('outlineids', target.attr('outlineids') + ',' + VisualService.currentdragline.attr('id'))

        //event.sourceEvent.stopPropagation();
      })
      .on("end", function (event) {  //dragend的监听器
        console.log("搁曳结束");

        //event.sourceEvent.stopPropagation();
      })
      .on("drag", function (event) {
        //console.log(d);

        let mx = event.sourceEvent.offsetX
        let my = event.sourceEvent.offsetY
        console.log(event);

        dragmove(mx, my)

        // VisualService.currentdragline.attr('x2', mx)
        // VisualService.currentdragline.attr('y2', my)
        //event.sourceEvent.stopPropagation();


      });

    let activePoint = VisualService.drawRectangle(canvasId, pointx - pointR, pointy - pointR, pointx + pointR, pointy + pointR, "1px", "black", "white", '')
    activePoint.call(drag);
    activePoint.attr('tag', tag)
    activePoint.attr("id", id)
    console.log(id);
    activePoint.attr("class", VisualService.activepoint)//所有的激活点都是同一类
    activePoint.attr("style", "cursor:" + cursor)


    return (activePoint)
  }
  public static addLinkPoint(canvasId, target, pointx, pointy, pointR, id: string, tag: string) {
    this.selectedrectid = target.attr('id')

    let drag = d3.drag()
      .on("start", function (event) { //dragstart的监听器
        console.log("拖曳开始");

        VisualService.currentdragline = VisualService.drawLine(canvasId, event.sourceEvent.offsetX, event.sourceEvent.offsetY, event.sourceEvent.offsetX, event.sourceEvent.offsetY, 2, 'black', true)
        target.attr('outlineids', target.attr('outlineids') + ',' + VisualService.currentdragline.attr('id'))

        //VisualService.currentdragline.setAttribute("pointer-events", "none")//线不能屏蔽底层的事件响应
        //event.sourceEvent.stopPropagation();
      })
      .on("end", function (event) {  //dragend的监听器
        console.log("搁曳结束");
        console.log(VisualService.currentdragline);
        if (VisualService.currentlinkpoint !== undefined) {
          if (VisualService.currentdragline !== undefined) {
            target.attr('inlineids', target.attr('inlineids') + ',' + VisualService.currentdragline.attr('id'))
            VisualService.currentdragline = undefined
          }
        }
        //event.sourceEvent.stopPropagation();
      })
      .on("drag", function (event) {
        //console.log(d);

        let mx = event.sourceEvent.offsetX
        let my = event.sourceEvent.offsetY
        //console.log(event);

        var t = d3.select(this);

        VisualService.currentdragline.attr('x2', mx)
        VisualService.currentdragline.attr('y2', my)
        //event.sourceEvent.stopPropagation();


      });

    let activePoint = VisualService.drawCircle(canvasId, pointx, pointy, pointR, "1px", "black", "white")
    activePoint.call(drag);
    activePoint.attr('tag', tag)
    activePoint.attr("id", id)
    activePoint.attr("class", VisualService.activepoint)//所有的激活点都是同一类
    activePoint.on("mouseover", function (d, i) {
      VisualService.currentlinkpoint = activePoint
      d3.select(this).attr("fill", "black"); //当鼠标移到元素上时，元素为黄色						
    })
      .on("mouseout", function (d, i) {
        d3.select(this)//当鼠标移到元素上时，元素过渡到原来的颜色
          .transition()
          .duration(500)
          .attr("fill", "white");
      })
      .on("mouseup", function (d, i) {
        console.log('on mouse up');
        if (VisualService.currentdragline !== undefined) {
          target.attr('inlineids', target.attr('inlineids') + ',' + VisualService.currentdragline.attr('id'))
          VisualService.currentdragline = undefined
        }
      })
      .on("drop", function (d, i) {
        console.log('on drop');
        if (VisualService.currentdragline !== undefined) {
          target.attr('inlineids', target.attr('inlineids') + ',' + VisualService.currentdragline.attr('id'))
          VisualService.currentdragline = undefined
        }
      })

    return (activePoint)
  }
  //激活显示四个缩放点，在角部，四个连接点，在中部
  public static activeRect(canvasId, target, pointR) {
    this.selectedrectid = target.attr('id')

    let baseid = target.attr("id")
    //let line = undefined

    // let activepointdrag = d3.drag()
    //   .on("start", function (event) { //dragstart的监听器
    //     console.log("拖曳开始");

    //     VisualService.currentdragline = VisualService.drawLine(canvasId, event.sourceEvent.offsetX, event.sourceEvent.offsetY, event.sourceEvent.offsetX, event.sourceEvent.offsetY, 2, 'black')
    //     target.attr('outlineids', target.attr('outlineids') + ',' + VisualService.currentdragline.attr('id'))

    //     event.sourceEvent.stopPropagation();
    //   })
    //   .on("end", function (event) {  //dragend的监听器
    //     console.log("搁曳结束");

    //     event.sourceEvent.stopPropagation();
    //   })
    //   .on("drag", function (event) {
    //     //console.log(d);

    //     let mx = event.sourceEvent.offsetX
    //     let my = event.sourceEvent.offsetY
    //     console.log(event);

    //     var t = d3.select(this);

    //     VisualService.currentdragline.attr('x2', mx)
    //     VisualService.currentdragline.attr('y2', my)
    //     event.sourceEvent.stopPropagation();


    //   });

    let r = []

    let leftx = target.attr("x")
    let lefty = Number(target.attr("y")) + Number(target.attr("height")) / 2
    let topx = Number(target.attr("x")) + Number(target.attr("width")) / 2
    let topy = target.attr("y")
    let rightx = Number(target.attr("x")) + Number(target.attr("width"))
    let righty = Number(target.attr("y")) + Number(target.attr("height")) / 2
    let bottomx = Number(target.attr("x")) + Number(target.attr("width")) / 2
    let bottomy = Number(target.attr("y")) + Number(target.attr("height"))


    //let activePoint = VisualService.drawCircle(canvasId, leftx, lefty, pointR, "1px", "black", "white")
    let activePoint = VisualService.addLinkPoint(canvasId, target, leftx, lefty, pointR, VisualService.linkpointclass + '_l_' + baseid, 'l')
    //activePoint.call(activepointdrag);
    //activePoint.attr('tag', "l")
    //activePoint.attr("id", 'activepointl' + baseid)
    //activePoint.attr("class", "activepoint")//所有的激活点都是同一类
    // activePoint.on("mouseover", function (d, i) {

    //   d3.select(this).attr("fill", "black"); //当鼠标移到元素上时，元素为黄色						
    // })
    //   .on("mouseout", function (d, i) {
    //     d3.select(this)//当鼠标移到元素上时，元素过渡到原来的颜色
    //       .transition()
    //       .duration(500)
    //       .attr("fill", "white");
    //   })
    //   .on("mouseup", function (d, i) {
    //     if (VisualService.currentdragline !== undefined) {
    //       target.attr('inlineids', target.attr('inlineids') + ',' + VisualService.currentdragline.attr('id'))
    //       VisualService.currentdragline = undefined

    //     }
    //   })

    r.push(activePoint)

    //activePoint = VisualService.drawCircle(canvasId, topx, topy, pointR, "1px", "black", "white")
    activePoint = VisualService.addLinkPoint(canvasId, target, topx, topy, pointR, VisualService.linkpointclass + '_t_' + baseid, 't')
    //activePoint.call(activepointdrag);
    //activePoint.attr('tag', "t")
    //activePoint.attr("id", 'activepointt' + baseid)
    // activePoint.on("mouseover", function (d, i) {
    //   d3.select(this).attr("fill", "black"); //当鼠标移到元素上时，元素为黄色						
    // })
    //   .on("mouseout", function (d, i) {
    //     d3.select(this)//当鼠标移到元素上时，元素过渡到原来的颜色
    //       .transition()
    //       .duration(500)
    //       .attr("fill", "white");
    //   });
    // activePoint.attr("class", "activepoint")
    // target.attr("activepointtop", activePoint)
    r.push(activePoint)

    // activePoint = VisualService.drawCircle(canvasId, rightx, righty, pointR, "1px", "black", "white")
    // activePoint.call(activepointdrag);
    // activePoint.attr('tag', "r")
    // activePoint.attr("id", 'activepointr' + baseid)
    // activePoint.on("mouseover", function (d, i) {

    //   d3.select(this).attr("fill", "black"); //当鼠标移到元素上时，元素为黑色						
    // })
    //   .on("mouseout", function (d, i) {
    //     d3.select(this)//当鼠标移到元素上时，元素过渡到原来的颜色
    //       .transition()
    //       .duration(500)
    //       .attr("fill", "white");
    //   });
    // target.attr("activepointright", activePoint)
    // activePoint.attr("class", "activepoint")
    activePoint = VisualService.addLinkPoint(canvasId, target, rightx, righty, pointR, VisualService.linkpointclass + '_r_' + baseid, 'r')
    r.push(activePoint)

    // activePoint = VisualService.drawCircle(canvasId, bottomx, bottomy, pointR, "1px", "black", "white")
    // activePoint.call(activepointdrag);
    // activePoint.attr('tag', "b")
    // activePoint.attr("id", 'activepointb' + baseid)
    // activePoint.on("mouseover", function (d, i) {
    //   d3.select(this).attr("fill", "black"); //当鼠标移到元素上时，元素为黄色						
    // })
    //   .on("mouseout", function (d, i) {
    //     d3.select(this)//当鼠标移到元素上时，元素过渡到原来的颜色
    //       .transition()
    //       .duration(500)
    //       .attr("fill", "white");
    //   });
    // target.attr("activepointbottom", activePoint)
    // activePoint.attr("class", "activepoint")
    activePoint = VisualService.addLinkPoint(canvasId, target, bottomx, bottomy, pointR, VisualService.linkpointclass + '_b_' + baseid, 'b')
    r.push(activePoint)

    r.push(VisualService.addLeftTopScalePoint(canvasId, target, pointR))
    r.push(VisualService.addRightTopScalePoint(canvasId, target, pointR))
    r.push(VisualService.addLeftBottomScalePoint(canvasId, target, pointR))
    r.push(VisualService.addRightBottomScalePoint(canvasId, target, pointR))

    return r
  }
  public static activeLine(canvasId, targetLine, pointR) {
    let r = []
    var drag = d3.drag()

      .on("dragstart", function (a) { //dragstart的监听器
        console.log("拖曳开始");
      })
      .on("dragend", function (d) {  //dragend的监听器
        console.log("搁曳结束");
      })
      .on("drag", function (event, node) {
        //console.log(d);
        console.log(d3.pointer(event, node));
        let mx = event.x
        let my = event.y
        let dx = event.dx
        let dy = event.dy

        var t = d3.select(this);
        t
          // 将d3.event.x赋值给被绑定的数据，再将cx属性设置为该值
          .attr("cx", mx)
        //将d3.event.y赋值给被绑定的数据，再将cy属性设置为该值
        t.attr("cy", my);
        targetLine.attr(t.attr("tagx"), mx)
        targetLine.attr(t.attr("tagy"), my)

        event.stopPropagation();
      });

    let activePoint = VisualService.drawCircle(canvasId, targetLine.attr("x1"), targetLine.attr("y1"), pointR, "1px", "black", "white")
    activePoint.call(drag);
    activePoint.attr('tagx', "x1")
    activePoint.attr('tagy', "y1")

    r.push(activePoint)
    activePoint = VisualService.drawCircle(canvasId, targetLine.attr("x2"), targetLine.attr("y2"), pointR, "1px", "black", "white")
    activePoint.call(drag);
    activePoint.attr('tagx', "x2")
    activePoint.attr('tagy', "y2")
    r.push(activePoint)
    return r
  }
  public static deactive(canvasId, cl) {

  }
  public static removeLine(canvasId) {
    let svg = VisualService.getCanvas(canvasId)
    svg.select('#' + VisualService.targetline.attr("id")).remove()
  }
  public static getCanvas(canvasId) {
    return d3.select(canvasId)
  }

  public static drawLine(canvasId, x1, y1, x2, y2, w, c, includeArrow = true) {
    let svg = this.getCanvas(canvasId)
    let line = svg.append("line")
      .attr("id", CommonService.getid('line'))
      .attr("x1", x1)
      .attr("y1", y1)
      .attr("x2", x2)
      .attr("y2", y2)
      .attr("stroke", c)
      .attr("stroke-width", w)
      .attr("isactive", false)
      .attr("pointer-events", "none")

    if (includeArrow) {
      var defs = svg.append("defs");
      var arrowMarker = defs.append("marker")
        .attr("id", "arrow")
        .attr("markerUnits", "strokeWidth")
        .attr("markerWidth", 15)
        .attr("markerHeight", 15)
        .attr("viewBox", "0 0 12 12")
        .attr("refX", 6)
        .attr("refY", 6)
        .attr("orient", "auto")
        .attr("fill", "#F00")


      var arrow_path = "M-8,2 L7,6 L-8,10 L-4,6 L-8,2";

      arrowMarker.append("path")
        .attr("d", arrow_path)
        .attr("fill", "#00F")
      //line.attr("marker-end", "url(#arrow)")

    }
    line.on("click", function () {
      if (line.attr("isactive") === 'false') {
        line.attr("isactive", true)
        VisualService.activeLine(canvasId, line, 3)

      }
    });
    VisualService.targetline = line
    console.log(line);
    return line
  }
  // static saveui(uielement) {
  //   console.log(uielement);
  //   console.log(uielement.attr('uiobj'));
  //   let n = uielement.attr('uiobj') as node
  //   console.log(n)
  //   console.log(n['left'])
  //   if (n !== undefined) {
  //     n['left'] = Number(uielement.attr("x"))
  //     n['top'] = Number(uielement.attr("y"))
  //     n['width'] = Number(uielement.attr("width"))
  //     n['height'] = Number(uielement.attr("height"))
  //   }
  // }
  static dragrect = (canvasId) => {
    let svg = VisualService.getCanvas(canvasId)
    let fixdeltax = 0
    let fixdeltay = 0
    return d3.drag()
      .on("start", function (event) { //dragstart的监听器
        console.log("拖曳开始");
        let tx = event.sourceEvent.offsetX
        let ty = event.sourceEvent.offsetY
        let dx = event.dx
        let dy = event.dy
        var t = d3.select(this);
        fixdeltax = tx - Number(t.attr("x"))
        fixdeltay = ty - Number(t.attr("y"))
        //event.sourceEvent.stopPropagation();
      })
      .on("end", function (event) {  //dragend的监听器
        console.log("搁曳结束");

        // if (saveui !== undefined)
        //   saveui()
        //event.sourceEvent.stopPropagation();
      })
      .on("drag", function (event) {
        console.log(event);

        let tx = event.sourceEvent.offsetX
        let ty = event.sourceEvent.offsetY
        let dx = event.dx
        let dy = event.dy


        var t = d3.select(this);
        t.attr("x", tx - fixdeltax)
        //将d3.event.y赋值给被绑定的数据，再将cy属性设置为该值
        t.attr("y", ty - fixdeltay);
        if (t.attr("isactive") === 'true') {
          VisualService.refreshActivePoint(canvasId, t, VisualService.activepointR)
          // let lp = svg.select('#' + VisualService.linkpointclass + '_l_' + t.attr("id"))
          // lp.attr("cx", t.attr("x"))
          // lp.attr("cy", Number(t.attr("y")) + Number(t.attr("height")) / 2)

          // let tp = svg.select('#' + VisualService.linkpointclass + '_t_' + t.attr("id"))
          // tp.attr("cy", t.attr("y"))
          // tp.attr("cx", Number(t.attr("x")) + Number(t.attr("width")) / 2)

          // let rp = svg.select('#' + VisualService.linkpointclass + '_r_' + t.attr("id"))
          // rp.attr("cx", Number(t.attr("x")) + Number(t.attr("width")))
          // rp.attr("cy", Number(t.attr("y")) + Number(t.attr("height")) / 2)

          // let bp = svg.select('#' + VisualService.linkpointclass + '_b_' + t.attr("id"))
          // bp.attr("cx", Number(t.attr("x")) + Number(t.attr("width")) / 2)
          // bp.attr("cy", Number(t.attr("y")) + Number(t.attr("height")))

          // let ltp = svg.select('#' + VisualService.scalepointclass + '_lt_' + t.attr("id"))
          // ltp.attr("x", t.attr("x"))
          // ltp.attr("y", t.attr("y"))

          // let rtp = svg.select('#' + VisualService.scalepointclass + '_rt_' + t.attr("id"))
          // rtp.attr("y", t.attr("y"))
          // rtp.attr("x", Number(t.attr("x")) + Number(t.attr("width")))

          // let lbp = svg.select('#' + VisualService.scalepointclass + '_lb_' + t.attr("id"))
          // lbp.attr("x", Number(t.attr("x")))
          // lbp.attr("y", Number(t.attr("y")) + Number(t.attr("height")))

          // let rbp = svg.select('#' + VisualService.scalepointclass + '_rb_' + t.attr("id"))
          // rbp.attr("x", Number(t.attr("x")) + Number(t.attr("width")))
          // rbp.attr("y", Number(t.attr("y")) + Number(t.attr("height")))
        }

        let outids = t.attr('outlineids') === null ? '' : t.attr('outlineids')

        let ids = outids.split(',')
        ids.forEach(id => {
          if (id !== 'null' && id !== '') {
            let r = svg.select('#' + id)
            if (r !== undefined)
              r.attr('x1', Number(r.attr('x1')) + dx).attr('y1', Number(r.attr('y1')) + dy)
          }
        });
        let inids = t.attr('inlineids') === null ? '' : t.attr('inlineids')

        ids = inids.split(',')
        ids.forEach(id => {
          if (id !== 'null' && id !== '') {
            let r = svg.select('#' + id)
            if (r !== undefined)
              r.attr('x2', Number(r.attr('x2')) + dx).attr('y2', Number(r.attr('y2')) + dy)
          }
        });
        //event.sourceEvent.stopPropagation();
      })
  }

  //把矩形整个在最前面复制一遍
  public static frontRectangle(canvasId) {
    if (VisualService.selectedrectid === undefined) {
      console.log('no selected rect');
      return
    }
    console.log('moving ' + VisualService.selectedrectid);
    let svg = VisualService.getCanvas(canvasId)
    let rect = svg.select('#' + VisualService.selectedrectid)

    let x = rect.attr('x')
    let y = rect.attr('y')
    let w = rect.attr('width')
    let h = rect.attr('height')

    let clonedrect = this.getCanvas(canvasId).append("rect")
      .attr("id", VisualService.selectedrectid)
      .attr("class", "node")
      .attr("x", x)
      .attr("y", y)
      .attr("width", w)
      .attr("height", h)
      .attr("fill", rect.attr('fill'))
      //.attr("fill", "red")
      .attr("stroke", rect.attr('stroke'))
      .attr("stroke-width", rect.attr('stroke-width'))
      .attr('inlineids', rect.attr('inlineids'))
      .attr('outlineids', rect.attr('outlineids'))

    clonedrect.on("click", function () {
      if (clonedrect.attr("isactive") === 'false') {
        clonedrect.attr("isactive", true)
        VisualService.activeRect(canvasId, clonedrect, 3)
      }
      event.stopPropagation();
    });
    clonedrect.call(VisualService.dragrect(canvasId))
    if (rect.attr("isactive") === 'true') {

      clonedrect.attr("isactive", true)
      VisualService.activeRect(canvasId, clonedrect, 3)

      svg.select('#activepointl' + VisualService.selectedrectid).remove()
      svg.select('#activepointt' + VisualService.selectedrectid).remove()
      svg.select('#activepointr' + VisualService.selectedrectid).remove()
      svg.select('#activepointb' + VisualService.selectedrectid).remove()
    }
    //svg.select('#' + selectedrectid).remove()
    console.log('clone success!');
    svg.select('#' + VisualService.selectedrectid).remove()
    return clonedrect
  }
  public static drawRectangle(canvasId, x1, y1, x2, y2, w, bc, fc, text) {

    let svg = this.getCanvas(canvasId)
    // let group = svg.append("g").attr("x", Math.min(x1, x2))
    //     .attr("y", Math.min(y1, y2)).attr("width", Math.abs(x1 - x2))
    //     .attr("height", Math.abs(y1 - y2))
    let rect = svg.append("rect")
      .attr("id", CommonService.getid('rect'))
      .attr("class", "node")
      .attr("x", Math.min(x1, x2))
      .attr("y", Math.min(y1, y2))
      .attr("width", Math.abs(x1 - x2))
      .attr("height", Math.abs(y1 - y2))
      .attr("fill", fc)
      .attr("stroke", bc)
      .attr("stroke-width", w)
      .attr("isactive", false)

    let t = VisualService.drawText(canvasId, x1, y1, text, 12)
    t.attr('id', 'text_' + rect.attr('id'))

    rect.on("click", function (event) {
      if (rect.attr("isactive") === 'false') {
        rect.attr("isactive", true)
        VisualService.activeRect(canvasId, rect, 3)

      }
      event.stopPropagation();
    });

    rect.call(VisualService.dragrect(canvasId))
    return rect
  }
  public static drawCircle(canvasId, cx, cy, r, w, bc, fc) {
    let svg = this.getCanvas(canvasId)
    let circle = svg.append("circle")
      .attr("cx", cx)
      .attr("cy", cy)
      .attr("r", r)
      .attr("fill", fc)
      .attr("stroke", bc)
      .attr("stroke-width", w)
    return circle
  }

  static showFocus = false

  public static focusHline = undefined
  public static focusVline = undefined
  public static showfocusline(canvasId) {
    let svg = this.getCanvas(canvasId)
    VisualService.showFocus = true
    svg
      .on("mousemove", function (event, i) {
        let tx = event.offsetX
        let ty = event.offsetY
        if (VisualService.showFocus) {
          if (VisualService.focusHline === undefined) {
            VisualService.focusHline = VisualService.drawLine(canvasId, 0, ty, svg.attr('width'), ty, 1, 'black', false)
          }
          if (VisualService.focusVline === undefined) {
            VisualService.focusVline = VisualService.drawLine(canvasId, tx, 0, tx, svg.attr('height'), 1, 'black', false)
          }
          VisualService.focusHline.attr('y1', ty)
          VisualService.focusHline.attr('y2', ty)
          VisualService.focusVline.attr('x1', tx)
          VisualService.focusVline.attr('x2', tx)
          console.log(event);

        }
      }, false)
  }

  static drawmode = false


  static drawenable = false



  public static getPointer(event) {
    return {
      x: event.offsetX,
      y: event.offsetY
    }
  }
  public static setLineInfo(uielement, link: link) {
    uielement.attr('class', 'node')
    uielement.attr('id', link.id)
    uielement.attr('dataid', link.dataId)
    uielement.attr('grade', link.grade)
    uielement.attr('text', link.text)
    uielement.attr('memo', link.memo)
  }
  public static setUIElementInfo(uielement, node: node) {
    uielement.attr('class', 'node')
    uielement.attr('id', node.id)
    uielement.attr('dataid', node.dataId)
    uielement.attr('entitytype', node.datatype)
    uielement.attr('text', node.text)
    uielement.attr('memo', node.memo)
  }
  public static createRect(canvasId, additional = undefined) {
    let svg = this.getCanvas(canvasId)
    let currentRect = undefined
    svg.on("mousedown", function (event, i) {
      if (VisualService.drawenable) {
        VisualService.drawmode = true
        console.log(event.x);
        let p = VisualService.getPointer(event)

        currentRect = VisualService.drawRectangle(canvasId, p.x, p.y, p.x, p.y, 2, 'black', 'white', 'default')
        currentRect.attr('class', 'node')
      }
    }, false)
      .on("mouseup", function (event, i) {
        console.log('draw up');

        if (VisualService.drawenable && VisualService.drawmode && additional !== undefined)
          additional(currentRect)
        VisualService.drawmode = false
        VisualService.drawenable = false
        currentRect = undefined
      })
      .on("mousemove", function (event, i) {
        if (VisualService.drawenable && VisualService.drawmode && currentRect !== undefined) {
          let tx = Number(currentRect.attr('x'))
          let ty = Number(currentRect.attr('y'))
          let p = VisualService.getPointer(event)
          currentRect.attr('width', Math.abs(tx - p.x))
          currentRect.attr('height', Math.abs(ty - p.y))
          currentRect.attr('x', Math.min(tx, p.x))
          currentRect.attr('y', Math.min(ty, p.y))
        }
      }, false)
      .on('click', function (d, i) {
        console.log('canvas click');
        d3.selectAll('.activepoint').remove()
        d3.selectAll('.node').attr("isactive", 'false')
      }, false)

    return currentRect
  }



  public static createStar(canvasId) {
    // 定义符号生成器
    var symbol = d3.symbol()
      .size(250)
      .type(function (d) { return d; });
    let svg = this.getCanvas(canvasId)
    let circle = svg.append("g")
      .attr("transform", function (d, i) {
        var x = 100;
        var y = 150;
        return "translate(" + x + ", " + y + ")";
      })
      //.attr('x', 250).attr('y', 200)
      .attr("stroke", 'black')
      .attr("stroke-width", 1)
      .append("path")
      .attr("d", function (d) { return symbol(d3.symbolStar); })
      // .attr("transform", function (d, i) {
      //     var x = 100;
      //     var y = 150;
      //     return "translate(" + x + ", " + y + ")";
      // })
      .attr("fill", 'red')
      .attr("stroke", 'black')
      .attr("stroke-width", 3)
      .append('text')
      .text('text')
      // .attr("x", 25)
      // .attr('y', 25)
      .attr('text-anchor', "middle")

    // 七种图形符号
    var dataSymbol = [d3.symbolCircle, d3.symbolCross, d3.symbolDiamond, d3.symbolSquare,
    d3.symbolStar, d3.symbolTriangle, d3.symbolWye];


    // 定义十种颜色
    var colors = d3.scaleOrdinal(d3.schemeCategory10);

    // 绘制
    svg.selectAll("path")
      .data(dataSymbol)
      .enter()
      .append("path")
      .attr("d", function (d) { return symbol(d); })
      .attr("transform", function (d, i) {
        var x = 10;
        var y = 10 + i * 80;
        return "translate(" + x + ", " + y + ")";
      })
      .attr("fill", function (d, i) { return colors[i]; })

  }

  public static createNodeShape(node) {

  }
  public static drawText(canvas, x, y, text, size) {
    let svg = d3.select(canvas);
    const height = +svg.attr("height");
    const width = +svg.attr("width");
    return svg
      .append("text")
      .attr("x", x)
      .attr("y", y)
      .attr("font-size", size)
      .text(text)
      .attr("stroke", "black")
      .attr("stroke-width", "0.5px");
  }
  public static writeDiagram(dgm: diagram, canvasId: string) {
    if (dgm === undefined)
      dgm = new diagram()
    let svg = this.getCanvas(canvasId)
    let nl = d3.selectAll('.node')
    let cl = d3.selectAll('.comment')
    let rl = d3.selectAll('.link')
    nl['_groups'][0].forEach(element => {
      console.log(element);
      console.log(element['attributes']['id']['value']);
      console.log(element['id']);
      console.log(element['attributes']['x']['value']);
      console.log(element['x']['value']);
      let id = element['id']
      let t = dgm.nodes.filter(v => v.id === id)
      let cn: node = undefined
      if (t === undefined || t.length === 0) {
        cn = new node()
        cn.id = id
        dgm.nodes.push(cn)
      }
      else
        cn = t[0]


      cn.dataId = element['attributes']['dataid']['value']
      cn.datatype = element['attributes']['entitytype']['value']
      cn.left = element['attributes']['x']['value']
      cn.top = element['attributes']['y']['value']
      cn.width = element['attributes']['width']['value']
      cn.height = element['attributes']['height']['value']
      cn.text = element['attributes']['text']['value']
      cn.memo = element['attributes']['memo']['value']
    });
    cl['_groups'][0].forEach(tc => {

      let id = tc['id']
      let t = dgm.comments.filter(v => v.Id === id)
      let c: comment = undefined
      if (t === undefined || t.length === 0) {
        c = new comment()
        c.Id = id
        dgm.comments.push(c)
      }
      else
        c = t[0]


      c.left = tc['attributes']['x']['value']
      c.top = tc['attributes']['y']['value']
      c.width = tc['attributes']['width']['value']
      c.height = tc['attributes']['height']['value']
      c.text = tc['attributes']['text']['value']
      c.linkx = tc['attributes']['linkx']['value']
      c.linky = tc['attributes']['linky']['value']
      c.iconmode = tc['attributes']['iconmode']['value']
      c.showlink = tc['attributes']['showlink']['value']
      c.fontsize = tc['attributes']['fontsize']['value']

    });
    rl['_groups'][0].forEach(r => {

      let id = r['id']
      let t = dgm.links.filter(v => v.id === id)
      let cn: link = undefined
      if (t === undefined || t.length === 0) {
        cn = new link()
        cn.id = id
        dgm.links.push(cn)
      }
      else
        cn = t[0]


      cn.dataId = r['attributes']['dataid']['value']

      cn.startX = r['attributes']['x1']['value']
      cn.startY = r['attributes']['y1']['value']
      cn.endX = r['attributes']['x2']['value']
      cn.endY = r['attributes']['y2']['value']
      cn.grade = r['attributes']['grade']['value']

    });
    // sl.each(v => {
    //   console.log(v);
    //   let id = v['attr']('id')
    //   console.log(id);
    //   let t = dgm.nodes.filter(v => v.objectId === id)
    //   let cn: node = undefined
    //   if (t === undefined || t.length === 0) {
    //     cn = new node(undefined)
    //     cn.objectId = id
    //     dgm.nodes.push(cn)
    //   }
    //   else
    //     cn = t[0]
    //   cn.dataId = v['attr']('dataId')

    // })
    console.log(dgm);
  }

  public static readDiagram(dgm: diagram, canvasId: string) {

    dgm.nodes.forEach(node => {
      console.log(node);
      console.log(node.left);
      console.log(node.width);
      let currentRect = VisualService.drawRectangle(canvasId, node.left, node.top, Number(node.left) + Number(node.width), Number(node.top) + Number(node.height), 2, 'black', 'white', node.text)
      currentRect.attr('class', 'node')

      VisualService.setUIElementInfo(currentRect, node)
    })
    dgm.links.forEach(link => {
      let l = VisualService.drawLine(canvasId, link.startX, link.startY, link.endX, link.endY, 2, 'black', true)
      l.attr('class', 'link')

      VisualService.setLineInfo(l, link)
    })
    dgm.comments.forEach(ct => {
      let l = VisualService.drawText(canvasId, ct.left, ct.top, ct.text, ct.fontsize)
      l.attr('class', 'comment')

      //VisualService.setUIElementInfo(currentRect, node)
    })
  }








  //#endregion


}
function none(arg0: string, none: any) {
  throw new Error('Function not implemented.');
}

